// $Id: node.h 75 2005-05-16 20:57:11Z jonas $
#ifndef NODE_H
#define NODE_H

#include <list>
#include <map>
#include <vector>
#include "storedfile.h"
#include "transfer.h"
#include "filehandler.h"
#include "noderequestfileparameters.h"
#include "routingentry.h"
#include "keydistancehelper.h"
class FileHandler;

// DEBUG:
#include <iostream>
using namespace std;

/**
 * This is the base class for all nodes. It provides some pure virtual methods
 * as well as some basic functionality and common data.
 */
class Node {
public:
	Node() : m_bandwidthUp(0), m_bandwidthDown(0) { cout << "Node::Node() Default constructor called. This should never happen. Bailing out!" << endl; exit(1); };	// FULHACK: To enable smoother virtual inherritance...
	Node(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, float, float, FileHandler *);
	virtual ~Node();

	virtual bool addNeighbor(Node *, unsigned int) = 0;
	std::list<RoutingEntry> *getNeighbors() { return &m_routingTable; }
	virtual void execute() = 0;
	virtual StoredFile *storeFile(File *, bool) = 0;
	StoredFile *getStoredFile(File *);
	int getFileStoreSize() { return m_fileStore.size(); }
	static FileHandler *getFileHandler() { return m_fileHandler; }
	bool insertFile(File *, int);
	virtual bool requestFile(File *, int);
	//virtual bool requestFile(unsigned int, Node *, File *, int &) = 0;
	virtual bool routeFile(Node *, NodeRequestFileParameters *) = 0;
	bool doRequest();
	bool doInsert();

	Transfer *getTransfer(int);
	Transfer *getTransfer(StoredFile *);
	int getTransferCount();
	unsigned int getBandwidthUp();
	unsigned int getBandwidthDown();

	float getInsertProbability();
	float getRequestProbability();
	void setInsertProbability(float);
	void setRequestProbability(float);

	/**
	 * @todo write doc here?
	 */
	virtual void generateRequestOrderList(File *, std::list<KeyDistanceHelper> &) = 0;

protected:
	std::map<File *, StoredFile *> m_fileStore;
	std::list<RoutingEntry> m_routingTable;
	std::vector<Transfer *> m_transfers;
	static unsigned int m_nextSearchGuid;
	static FileHandler *m_fileHandler;
	/**
	 * Freenet has room for 50 (or is it 100?) unique nodes, and 50 referenses to each node.
	 */
	unsigned int m_routingTableSize;
	unsigned int m_fileStoreSize;
	unsigned int m_requestHopsToLive;
	unsigned int m_insertHopsToLive;
	float m_requestProbability;
	float m_insertProbability;
	/// In bytes per time step
	const unsigned int m_bandwidthUp;
	/// In bytes per time step
	const unsigned int m_bandwidthDown;

	static bool iOne;	// DEBUG
	static bool iTwo;	// DEBUG

private:
};

#endif
